
package hk.ces.oxfam.patch.patchs;

import hk.ces.oxfam.patch.DBPatch;
import hk.ces.oxfam.patch.DBPatchTransaction;
import hk.ces.oxfam.patch.DBPatchTransactionType;
import hk.ces.oxfam.patch.db.result.ExcuteResult;
import hk.ces.oxfam.patch.db.sql.PreparedSQL;
import hk.ces.oxfam.patch.db.sql.SQLUtil;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author ReutyCheng
 */
@DBPatchTransaction(transactionType = DBPatchTransactionType.IN_PATCH)
public class PersonInfoTypeToDonorPatch implements DBPatch
{
  private static final String DONOR = "DONOR";

  public String getName()
  {
    return "Update Person Info Type to [DONOR] Patch";
  }

  public void patch(Connection connection) throws SQLException
  {
    List<Long> donorIds = this.getAllDonorIdFromTransaction(connection);
    int donorUpdatedResult = this.updateSelectedPersonInfoToDonor(connection, donorIds);

    Logger.getLogger(this.getClass()).debug("Totally update Donor[count=" + donorUpdatedResult + "]");
  }

  private List<Long> getAllDonorIdFromTransaction(Connection connection) throws SQLException
  {
    String sql = "select distinct donor_id from transaction";
    Object[] objects = new Object[]{};
    List<Long> donorIds = SQLUtil.certainColumn(connection, new PreparedSQL(sql, objects), Long.class);

    return donorIds;
  }

  private int updateSelectedPersonInfoToDonor(Connection connection, List<Long> donorIds) throws SQLException
  {
    int resultCount = 0;

    for (Long donorId : donorIds)
    {
      if (isPersonHaveDonorInfo(connection, donorId))
      {
        Logger.getLogger(this.getClass()).debug("Person[id=" + donorId + "] have PersonInfoType is [DONOR] personinfo, Ignore this person for update PersonInfoType of [DONOR]");
      }
      else
      {
        String sql = "update personinfo set personinfotype = ? where id = (select max(personinfolist_id) from person_personinfo where person_id = ?)";
        Object[] objects = new Object[] {
          DONOR,
          donorId
        };
        ExcuteResult result = SQLUtil.execute(connection, new PreparedSQL(sql, objects));
        Logger.getLogger(this.getClass()).debug(result.getExcuteStatus() + " : Person[id=" + donorId + "] have NOT PersonInfoType is [DONOR] personinfo, patch this person with PersonInfoType of [DONOR]");
        resultCount += result.getResultCount();
      }
    }

    return resultCount;
  }

  private boolean isPersonHaveDonorInfo(Connection connection, Long donorId) throws SQLException
  {
    String sql = "select count(id) from personinfo where id in (select personinfolist_id from person_personinfo where person_id = ?) and personinfotype = ?";
    Object[] objects = new Object[] {
      donorId,
      DONOR
    };

    Integer count = SQLUtil.single(connection, new PreparedSQL(sql, objects), Integer.class);
    return count != null && count > 0;
  }
}
